package com.sap.sap_mangers.component;

import com.sap.sap_mangers.Vo.BmsVo.BmsUserForTimeNoReturningVo;
import com.sap.sap_mangers.Vo.ShareVo.SapShareVo;
import com.sap.sap_mangers.dto.user.NoticeDto;
import com.sap.sap_mangers.email.IMailService;
import com.sap.sap_mangers.pojo.SapBmsManagerSimpleInfo;
import com.sap.sap_mangers.pojo.SapOnlinePeople;
import com.sap.sap_mangers.pojo.User;
import com.sap.sap_mangers.service.*;
import com.sap.sap_mangers.until.ConstantUntil;
import com.sap.sap_mangers.until.EmailUntil;
import com.sap.sap_mangers.until.RedisCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;


/**
 * 定时任务
 *
 * @author 谢添
 * @date 2022/8/10 23:55
 */
@Component
@EnableScheduling
@EnableAsync
@Slf4j
public class ScheduledTask {
    @Autowired
    BmsService bmsService;
    @Autowired
    IMailService iMailService;
    @Autowired
    UserService userService;

    @Autowired
    ShareService shareService;

    @Autowired
    CacheService cacheService;
    @Autowired
    DynamicService dynamicService;
    @Autowired
    private RedisCache redisCache;

    /**
     * [图书管理系统] 每个两个小时 检查书籍状态为 借阅中的，如果超过了预期归还时间，则将状态修改为 超时未归还
     */
    @Async
    @Scheduled(cron = "0 0 0/2 * * ?")
    public void updateAllBookTimeoutNoReturn() {
        bmsService.updateAllBookTimeoutNoReturn();
    }

    /**
     * [图书管理系统] 每天早上九点发一封邮件 发送给书籍超时未归还的人 --> 催促还书
     */
    @Async
    @Scheduled(cron = "0 0 9 * * ?")
    public void sendEmailForBookTimeoutNoReturn() {
        List<BmsUserForTimeNoReturningVo> userMessages = bmsService.getAllUserMessageForBookTimeoutNoReturn();
        if (userMessages == null || userMessages.size() == 0) {
            return;
        }
        List<SapBmsManagerSimpleInfo> sapBmsManagerSimpleInfos = bmsService.getSapBmsManagerSimpleInfos();
        StringBuilder failSendUserInfo = new StringBuilder();
        Exception exception = null;
        for (BmsUserForTimeNoReturningVo userMessage : userMessages) {
            try {
                String content = EmailUntil.sendEmailToUserAboutBookTimeoutNoReturning(userMessage, sapBmsManagerSimpleInfos);
                iMailService.sendHtmlMail(userMessage.getQq() + "@qq.com", "借阅书籍超时未归还", content);
                userService.sendNoticeAuto(new NoticeDto(userMessage.getUsername(), "借阅书籍超时未归还", null));
            } catch (Exception e) {
                exception = e;
                failSendUserInfo.append("<p>").append(userMessage.getRealName()).append(" QQ： ").append(userMessage.getQq()).append("</p>\n");
            }
        }
        try {
            if (!"".equals(failSendUserInfo.toString())) {
                User president = userService.getPresidentUserInfo();
                assert exception != null;
                String content = EmailUntil.failSendUserInfoForBookTimeoutNoReturn(failSendUserInfo.toString(), exception);
                iMailService.sendHtmlMail(president.getQq() + "@qq.com", "图书邮件或通知系统异常", content);
                userService.sendNoticeAuto(new NoticeDto(president.getUsername(), "借阅书籍超时未归还邮件或通知异常", null));
            }
        } catch (Exception e) {
            log.info("借阅书籍超时未归还邮件或通知异常,具体错误：{}", e.getMessage());
        }
    }

    /**
     * [入会升级系统] 检测过期的记录，将join_lapse字段改为1
     * <p>
     * 入会申请记录的create_time字段在每次点击申请按钮时都会刷新，填写过转账单号的记录不会过期
     * 检测create_time字段到当前时间大于24h的未填写单号的未过期记录，将其对应join_lapse字段改为1标识已过期
     */
    @Async
    @Scheduled(cron = "0 0 0/2 * * ?")
    public void detectExpiredJoinApplicationRecords() {
        userService.detectExpiredJoinApplicationRecords();
    }



    @Async
    @Scheduled(cron = "0 0 0/2 * * ?")
    public void countTheNumberOfPeople() {
        Set<String> peopleNum = redisCache.getCacheSet(ConstantUntil.CONFIRM_ONLINE_PEOPLE);
        Map<String, Object> onlineData = redisCache.getCacheMap(ConstantUntil.ONLINE_PEOPLE_DATA);
        if (onlineData.size() > 12) {
            for (String s : onlineData.keySet()) {
                onlineData.remove(s);
                break;
            }
        }
        SimpleDateFormat df = new SimpleDateFormat("HH:00:00");
        Date date = new Date();
        //这里减掉两小时(统计的时间加入是0:00，但是统计的是22:00-0:00之间的人数)
        String preTime = df.format(date.getTime()-1000*60*60*2);
        String nowTime=df.format(date.getTime());
        String time=preTime+"-"+nowTime;
        onlineData.put(preTime, peopleNum.size());
        SimpleDateFormat fullDf = new SimpleDateFormat("yyyy-MM-dd");
        Date fullDate = new Date();
        String fullTime = fullDf.format(fullDate);
        if (peopleNum.size() != 0) {
            for (String username : peopleNum) {
                userService.addOnlinePeople(new SapOnlinePeople(username, cacheService.getRealNameCache(cacheService.getRealNameCacheMap(), username), time, fullTime));
            }
        }
        Integer highestOnlinePeople = dynamicService.getHighestOnlinePeople();
        if (peopleNum.size() > highestOnlinePeople) {
            dynamicService.setHighestOnlinePeople(String.valueOf(peopleNum.size()));
        }
        redisCache.deleteObject(ConstantUntil.CONFIRM_ONLINE_PEOPLE);
        redisCache.deleteObject(ConstantUntil.ONLINE_PEOPLE_DATA);
        redisCache.setCacheMap(ConstantUntil.ONLINE_PEOPLE_DATA, onlineData);
    }

    @Async
    @Scheduled(cron = "0 0 0 * * ?")
    public void redisExpirationTime(){
        Map<String, Integer> time = redisCache.getCacheMap(ConstantUntil.SAP_LOGIN_TIME);
        for (String key : time.keySet()) {
            Integer value = time.get(key);
            if(value>0){
                value-=1;
                time.put(key,value);
            }else{
                time.remove(key);
            }
        }
        redisCache.deleteObject(ConstantUntil.SAP_LOGIN_TIME);
        redisCache.setCacheMap(ConstantUntil.SAP_LOGIN_TIME,time);
    }

    /**
     * 退出软件协会学习小组验证码时长
     */
    @Async
    @Scheduled(cron = "0 0 0 * * ?")
    public void redisExpirationTimeForQuitSawbs(){
        Map<String, Integer> time = redisCache.getCacheMap(ConstantUntil.CACHE_SAWBS_QUIT_CODE_TIME);
        for (String key : time.keySet()) {
            Integer value = time.get(key);
            if(value>0){
                value-=1;
                time.put(key,value);
            }else{
                time.remove(key);
            }
        }
        redisCache.deleteObject(ConstantUntil.CACHE_SAWBS_QUIT_CODE_TIME);
        redisCache.setCacheMap(ConstantUntil.CACHE_SAWBS_QUIT_CODE_TIME,time);
    }


}
